package com.jblv.frame.web.filter;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * @author happyonion.yangtao
 * @version 1.0
 * @title FrameHttpServletRequestWrapper
 * @projectName jblv-frame
 * @packageName com.jblv.web.filter
 * @description 读取body参数
 * @date Create at 2020/5/8 16:59
 * @since jdk1.8
 */
public class FrameHttpServletRequestWrapper extends HttpServletRequestWrapper {

    private final String requestBody;

    private Map<String, String[]> params = new HashMap<String, String[]>();

    public FrameHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        this.params.putAll(request.getParameterMap());
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            ServletInputStream inputStream = request.getInputStream();
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            if (bufferedReader != null) {
                char[] charBuffer = new char[128];
                int byteRead = -1;
                while ((byteRead = bufferedReader.read(charBuffer)) > 0) {

                    stringBuilder.append(charBuffer, 0, byteRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        requestBody = stringBuilder.toString();
    }

    public void setParameter(String key, Object value) {
        if (value != null) {
            if (value instanceof String[]) {
                params.put(key, (String[]) value);
            } else if (value instanceof String) {
                params.put(key, new String[]{(String) value});
            } else {
                params.put(key, new String[]{String.valueOf(value)});
            }
        }
    }

    public void setParameterMap(Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            setParameter(entry.getKey(), entry.getValue());
        }
    }

    @Override
    public String getParameter(String key) {
        String[] values = params.get(key);
        if (values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    @Override
    public String[] getParameterValues(String key) {
        return params.get(key);
    }

    public Map<String, String[]> getMyParameterMap() {
        return params;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody.getBytes());

        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    public String getBody() {
        return requestBody;
    }
}
